#region License

/* Copyright (c) 2008, Dusty Candland
 * 
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 * * Neither the name of Dusty Candland nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#endregion

using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Xml;

namespace NS3Library.Amazon
{
    public class AwsBucket : AbstractS3Bucket, IHaveAwsS3Status
    {
        private readonly int _contentLength;
        private readonly byte[] _content;
        private readonly bool _hasContent;
        private readonly string _createBucketConfigurationXmlName = "<CreateBucketConfiguration />";
        private readonly string _locationconstraintXmlName = "LocationConstraint";
        private readonly AwsStatus _awsStatus;

        public AwsBucket(string name)
            : base(name)
        {
        }

        public AwsBucket(string name, S3LocationConstraint locationConstraint, S3Acl acl)
            : base(name, locationConstraint, acl)
        {
            if (locationConstraint != S3LocationConstraint.None)
            {
                _content = Encoding.UTF8.GetBytes(GetCreateBucketConfiguration().OuterXml);
                _contentLength = _content.Length;
                _hasContent = true;
            }
        }

        public AwsBucket(string bucket, string prefix, int maxKeys, string marker, string delimiter, bool isTruncated,
                         IEnumerable<IS3ObjectKey> keys)
            : base(bucket, prefix, maxKeys, marker, delimiter, isTruncated, keys)
        {
        }

        public AwsBucket(string name, string prefix, int maxKeys, string marker, string delimiter)
            : base(name, prefix, maxKeys, marker, delimiter)
        {
        }

        public AwsBucket(IS3Bucket awsBucket, AwsStatus responseAwsStatus)
            : this(awsBucket.Name, awsBucket.Prefix, awsBucket.MaxKeys, awsBucket.Marker,
                   awsBucket.Delimiter, awsBucket.IsTruncated, awsBucket.S3ObjectKeys)
        {
            _awsStatus = responseAwsStatus;
        }

        public AwsStatus AwsStatus
        {
            get { return _awsStatus; }
        }

        public int ContentLength
        {
            get { return _contentLength; }
        }

        public byte[] Content
        {
            get { return _content; }
        }

        public bool HasContent
        {
            get { return _hasContent; }
        }

        private XmlDocument GetCreateBucketConfiguration()
        {
            if (LocationConstraint == S3LocationConstraint.None)
                return null;

            var xml = new XmlDocument();
            xml.LoadXml(_createBucketConfigurationXmlName);

            if (LocationConstraint != S3LocationConstraint.None)
            {
                XmlElement lce = xml.CreateElement(_locationconstraintXmlName);
                lce.AppendChild(xml.CreateTextNode(LocationConstraint.ToString()));
                xml.DocumentElement.AppendChild(lce);
            }

            return xml;
        }

        public bool WasFound
        {
            get
            {
                return (_awsStatus != null
                        && _awsStatus.HttpStatus != HttpStatusCode.NoContent
                        && _awsStatus.HttpStatus != HttpStatusCode.NotFound);
            }
        }
    }
}